package Server ;

import java.io.*;

import java.math.BigInteger;
import java.net.*;

import Helpers.ServerMethods;
import Paillier.Paillier;

class TCPServer implements Runnable
{
	Socket socket;
	Paillier p;
	public TCPServer(Socket socket,Paillier p)
	{
		this.socket = socket;
		this.p = p;
	}
	
   public void run () 
      {
         String fromclient = null;
		 PrintWriter outToClient = null;
         BufferedReader inFromClient = null;
         System.out.println( "THE CLIENT"+" "+socket.getInetAddress() +":"+socket.getPort()+" IS CONNECTED ");
         BigInteger n = null;
         BigInteger g = null;
     
			try {
				inFromClient = new BufferedReader(new InputStreamReader (socket.getInputStream()));
				outToClient = new PrintWriter(socket.getOutputStream(),true);
				
			} catch (IOException e) {
				e.printStackTrace();
			}
            
            	
			int count = 0;
			try {
				while(true)
	            {
					count++;
					if(count < 5)
					{
		            	ServerMethods sm = new ServerMethods(); 
		            	fromclient = inFromClient.readLine();
		            	System.out.println(fromclient);
		            	if(!fromclient.startsWith("keys"))
		            	{
		            		fromclient = p.Decrypt(fromclient);
		            	}
		            	String [] fromclientSp = fromclient.split("#");
		            	for(int i=0;i<fromclientSp.length;i++)
		            	{
		            		System.out.println(fromclientSp[i]);
		            	}
		            	if(fromclientSp[0].equals("login"))
		            	{
		            		String student = sm.loginStudent(fromclientSp[1], fromclientSp[2]);
		            		if(!student.equals(""))
		            		{
		            			String s = "student#"+student;
		            			String enc = p.EncryptByNG(s, n, g);
		            			outToClient.println(enc);
		            			break;
		            		}
		            		else
		            		{
		            			String admin = sm.loginAdmin(fromclientSp[1], fromclientSp[2]);
		            			if(!admin.equals(""))
		                		{
		            				String s = "admin#"+admin;
		                			String enc = p.EncryptByNG(s, n, g);
		                			outToClient.println(enc);
		                			break;
		                		}
		            			else
		            			{
		            				outToClient.println("");
		            				break;
		            			}
		            		}
		            		
		            	}
		            	else if(fromclientSp[0].equals("candCanVote"))
		            	{
		            		String s = sm.getCandidatesThatCanBeVoted(fromclientSp[1],fromclientSp[2]);
		        			String enc = p.EncryptByNG(s, n, g);
		        			outToClient.println(enc);
		            		break;
		            	}
		            	else if(fromclientSp[0].equals("insVote"))
		            	{
		            		String s = sm.insertVote(fromclientSp[1], Integer.parseInt(fromclientSp[2]))+"";
		        			String enc = p.EncryptByNG(s, n, g);
		        			outToClient.println(enc);
		            		break;
		            	}
		            	else if(fromclientSp[0].equals("addPanel"))
		            	{
		            		String s = sm.insertPanel(fromclientSp[1])+"";
		        			String enc = p.EncryptByNG(s, n, g);
		        			outToClient.println(enc);
		            		break;
		            	}
		            	else if(fromclientSp[0].equals("getPanels"))
		            	{
		            		String s = sm.getPanels();
		        			String enc = p.EncryptByNG(s, n, g);
		        			outToClient.println(enc);
		            		break;
		            	}
		            	else if(fromclientSp[0].equals("keys"))
		            	{
		            		n = new BigInteger(fromclientSp[1]);
		            		g = new BigInteger(fromclientSp[2]);
		            		outToClient.println("keys#"+p.n+"#"+p.g);
		            	}
	            }
				else
				{
					socket.close();
	            	inFromClient.close();
	            	outToClient.close();
	            	break;
				}
	           }
			}
			catch (IOException e){
				e.printStackTrace();
			}
			try {
				socket.close();
				inFromClient.close();
	        	outToClient.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	
        }
}

